﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ProtoBuf.Message;

namespace UI
{
    public class UIFormationPopupPage : Page
    {
        protected override void DoOpen()
        {
            base.DoOpen();

            titleAlpha.ResetToBeginning();
            titlePosition.ResetToBeginning();
            bodyScale.ResetToBeginning();

            titleAlpha.PlayForward();
            titlePosition.PlayForward();
            bodyScale.PlayForward();

            bkAlpha.ResetToBeginning();
            bkAlpha.PlayForward();

            foreach (var obj in heroNamebk)
            {
                obj.SetActive(false);
            }

#if UNITY_EDITOR
            foreach (var it in StaticData.playerData.InstPlayerData.BattleCamps)
            {
                Debug.Log("[DEBUG]->>>> battle pos:" + it.Value.battlePos + " hero id:" + it.Value.heroName);
            }
#endif

            StartCoroutine(_Init());
        }


		GameObject simpleShadowTex;

        IEnumerator _Init()
        {
            if (models.Count > 0)
            {
                foreach (var obj in models)
                {
                    GameObject.DestroyImmediate(obj);
                }

                foreach(var tr0 in modelTransform)
                {
                    tr0.GetComponent<UIFormationModel>().model = null;
                }

                models.Clear();
            }
            
            yield return new WaitForSeconds(titleAlpha.duration + bodyScale.duration);

            _ShowBtn();

            //List<int> notSetIndex = new List<int>();

            for (int i = 0; i < 4; i++)
            {
                var obj = StaticData.playerData.InstPlayerData.GetBattleCamp(i + 1);
                
                if (obj.hero != null)
                {
                    var uri = obj.hero.heroData.resName;
                    //var model = GameObject.Instantiate(Resources.Load(@"model/" + uri)) as GameObject;
                    var scale = (float)obj.hero.heroData.ScaleFactor;

                    GameObject model = null;
                    yield return StartCoroutine(ResourceLoader.GetInstance().modelLoader.LoadModel(uri, (asset)=> {
                        model = asset as GameObject;
                    }));

                    model.name = obj.hero.guid;
                    model.SetActive(true);
                    model.transform.SetParent(transform);
                    model.transform.localPosition = Vector3.zero;
                    model.transform.localRotation = Quaternion.Euler(new Vector3(0, 180, 0));
                    model.GetComponent<ModelRenderKit>().SetModelScale(scale);
                  

                    string equipId = "";
                    if( obj.equipments.Length>0 && 
                        obj.equipments[0]!=null && 
                        !string.IsNullOrEmpty(obj.equipments[0].equipId))
                    {
                        equipId = obj.equipments[0].equipId;
                    }
                    yield return StartCoroutine(model.GetComponent<ModelRenderKit>().LoadWeapons(obj.hero.heroId, equipId));

                    if (simpleShadowTex == null)
                    {
						simpleShadowTex = Resources.Load<GameObject>("texture/QuadShadow");
                    }

                    model.GetComponent<ModelRenderKit>().ShowSimpleShadow(simpleShadowTex);


                    foreach (var tr in model.GetComponentsInChildren<Transform>())
                    {
                        tr.gameObject.layer = LayerMask.NameToLayer("SceneActor");
                    }
                    


                    int n = 0;
                    foreach (var tr in modelTransform)
                    {
                        int pos = int.Parse(tr.gameObject.name);
                        if (pos == obj.battlePos)
                        {
                            shadowTransform[n].gameObject.SetActive(true);
                            modelScales[n] = (float)obj.hero.heroData.ScaleFactor;
                            tr.gameObject.GetComponent<UIFormationModel>().SetModel(model, shadowTransform[n].gameObject, obj.hero.heroData.id);
                            tr.gameObject.SetActive(false);
                            break;
                        }
                        n++;
                    }

                   

                    models.Add(model);

                    //string heroName = TableTextBlo.GetText(obj.hero.heroData.name);
                    string heroName = CommonMethod.GetHeroName(obj.hero.heroData.id);
                    int index = GetCampPosition(obj.battlePos) - 1;

                    ShowHeroName(index, heroName);

                    yield return null;
                }
                else
                {
                    int n = 0;
                    foreach (var tr in modelTransform)
                    {
                        if (tr.GetComponent<UIFormationModel>().model == null)
                        {
                            var model = new GameObject("hero:object:" + (i));
                            model.SetActive(false);
                            models.Add(model);

                            obj.battlePos = int.Parse(tr.name);
                            shadowTransform[n].gameObject.SetActive(false);

                            tr.gameObject.GetComponent<UIFormationModel>().SetModel(model, shadowTransform[n].gameObject, "-1");
                            break;
                        }

                        n++;
                    }
                }
            }
            
            ResetModelSize();
            powerItem.SetActive(true);
            dragTip.gameObject.SetActive(true);
            totalForce.text = StaticData.playerData.InstPlayerData.GetFightPower() + "";



        }


        protected override void DoClose()
        {
            if (models.Count > 0)
            {
                foreach (var obj in models)
                {
                    GameObject.DestroyImmediate(obj);
                }

                foreach (var tr0 in modelTransform)
                {
                    tr0.GetComponent<UIFormationModel>().model = null;
                }

                models.Clear();
            }

            HideBtn();
            isPress = false;

            powerItem.SetActive(false);
            dragTip.gameObject.SetActive(false);

            currentPosition = Vector3.zero;
            clickedOffset = Vector3.zero;
            StopAllCoroutines();
        }

        void _ShowBtn()
        {
            btn.SetActive(true);
        }

        void HideBtn()
        {
            btn.SetActive(false);
        }

        void ShowHeroName(int index, string heroName)
        {
            if (string.IsNullOrEmpty(heroName))
            {
                heroNamebk[index].SetActive(false);
            }
            else
            {
                heroNamebk[index].SetActive(true);
                heroNames[index].text = heroName;
            }
        }


        public Transform[] modelTransform;
        public Transform[] fixedTransform;
        public Transform[] shadowTransform;
        public float[] modelScales=new float[4] { 1,1,1,1};

        public UILabel[] heroNames;
        public GameObject[] heroNamebk;


        public Camera cam;
        public bool isPress = false;
        public GameObject selection;

        public int currentSelectionIndex = -1;

        public int willReplaceIndex = -1;

        public Vector3 currentPosition = Vector3.zero;
        public Vector3 clickedOffset = Vector3.zero;

        const float minSwitchPos = 50f;

        public TweenPosition titlePosition;
        public TweenScale bodyScale;
        public TweenAlpha titleAlpha;
        public TweenAlpha bkAlpha;

        public GameObject btn;

        public UILabel totalForce;

        List<GameObject> models = new List<GameObject>();

        public UILabel embattle;//布阵
        public UILabel dragTip;//拖动可调整位置

        public GameObject powerItem;
        //public Camera cam;

        void Awake()
        {
            //cam = UICamera.mainCamera;
            embattle.text = TableTextBlo.GetText("embattle");
            dragTip.text = TableTextBlo.GetText("drag_hero_tip");
        }

        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                isPress = true;
                currentPosition = Input.mousePosition;
                clickedOffset = Vector3.zero;
            }
            if (Input.GetMouseButtonUp(0))
            {
                isPress = false;

                currentPosition = Vector3.zero;
                clickedOffset = Vector3.zero;

                OnPressedRelease();


            }
            if (isPress)
            {
                if (selection == null)
                {
                    GetSelection();
                }
                currentPosition = Input.mousePosition;
            }

            if (selection != null)
            {
                var fixedZ = selection.transform.position.z;
                var selectionScreenPos = cam.WorldToScreenPoint(selection.transform.position);
                selectionScreenPos = currentPosition;
                selection.transform.position = cam.ScreenToWorldPoint(selectionScreenPos + clickedOffset);
                selection.transform.position = new Vector3(selection.transform.position.x, selection.transform.position.y, fixedZ);
            }
        }


        void GetSelection()
        {
            var ray = cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 1000, 1<<LayerMask.NameToLayer("SceneActor")))
            {
#if UNITY_EDITOR
                Debug.Log("[DEBUG current click:]" + hit.collider.gameObject.name);
#endif
                if (hit.collider.gameObject.GetComponent<UIFormationModel>() == null)
                    return;

                selection = hit.collider.gameObject;
                if (clickedOffset == Vector3.zero)
                {
                    clickedOffset = cam.WorldToScreenPoint(selection.transform.position) - currentPosition;
                }

                for (int i = 0; i < modelTransform.Length; ++i)
                {
                    currentSelectionIndex = i;
                    if (modelTransform[i].gameObject == selection) break;
                }
            }
#if UNITY_EDITOR
            Debug.DrawLine(ray.origin, hit.point, Color.red);
#endif
        }

        void SetReplaceIndex(int index0,int index1)
        {
            if(currentSelectionIndex == index0)
            {
                willReplaceIndex = index1;
            }
            else
            {
                willReplaceIndex = index0;
            }
        }

        int GetBattlePosition(int index)
        {
            if (index == 0) return 3;
            if (index == 1) return 7;
            if (index == 2) return 9;
            if (index == 3) return 13;

            return -1;
        }

        int GetCampPosition(int pos)
        {
            if (pos == 3) return 1;
            if (pos == 7) return 2;
            if (pos == 9) return 3;
            if (pos == 13) return 4;

            return -1;
        }

        void OnPressedRelease()
        {
            //找出与那个位子最近
            var screenPos0 = cam.WorldToScreenPoint(modelTransform[0].position);
            var screenPos1 = cam.WorldToScreenPoint(modelTransform[1].position);
            var screenPos2 = cam.WorldToScreenPoint(modelTransform[2].position);
            var screenPos3 = cam.WorldToScreenPoint(modelTransform[3].position);

            var pos0 = new Vector2(screenPos0.x, screenPos0.y);
            var pos1 = new Vector2(screenPos1.x, screenPos1.y);
            var pos2 = new Vector2(screenPos2.x, screenPos2.y);
            var pos3 = new Vector2(screenPos3.x, screenPos3.y);

            var dis0 = Vector2.Distance(pos0, pos1); //1-2
            var dis1 = Vector2.Distance(pos0, pos2); //1-3
            var dis2 = Vector2.Distance(pos1, pos3); //2-4
            var dis3 = Vector2.Distance(pos2, pos3); //3-4
            var dis4 = Vector2.Distance(pos0, pos3); //1-4
            var dis5 = Vector2.Distance(pos1, pos2); //2-3;

            #region switchpos
            if (dis0 < minSwitchPos)
            {
                SetReplaceIndex(0, 1);
                SwitchTwoPosition(0, 1);
            }
            else if (dis1 < minSwitchPos)
            {
                SetReplaceIndex(0, 2);
                SwitchTwoPosition(0, 2);
            }
            else if (dis2 < minSwitchPos)
            {
                SetReplaceIndex(1, 3);
                SwitchTwoPosition(1, 3);
            }
            else if (dis3 < minSwitchPos)
            {
                SetReplaceIndex(2, 3);
                SwitchTwoPosition(2, 3);
            }
            else if (dis4 < minSwitchPos)
            {
                SetReplaceIndex(0, 3);
                SwitchTwoPosition(0, 3);
            }
            else if (dis5 < minSwitchPos)
            {
                SetReplaceIndex(1, 2);
                SwitchTwoPosition(1, 2);
            }
            else
            {
                ResetPosition(currentSelectionIndex);
            }

            #endregion

            selection = null;
            currentSelectionIndex = -1;
            willReplaceIndex = -1;
        }

        void SwitchTwoPosition(int index0, int index1)
        {
            CommitFormationChange( index0, index1);
        }

        void CommitFormationChange(int index0, int index1)
        {
            CSFormationChange change = new CSFormationChange();

            string str = "";
            string oldStr = "";
           

            int index = 0;
            foreach(var tr in modelTransform)
            {
                index++;

                var model = tr.GetComponent<UIFormationModel>().model;

                if (!model.activeSelf) continue;

                for(int i=1;i<=4;i++)
                {
                    var F = StaticData.playerData.InstPlayerData.GetBattleCamp(i);
                    if (F.hero != null && model.name == F.hero.guid)
                    {
                        int trueIndex = index - 1;
                        
                        oldStr += "" + F.campPos + "," + GetBattlePosition(trueIndex) + ";";

                        if (trueIndex == index0)
                        {
                            trueIndex = index1;
                        }
                        else if (trueIndex == index1)
                        {
                            trueIndex = index0;
                        }


                        str += "" + F.campPos + "," + GetBattlePosition(trueIndex) + ";";
                    }
                }

            }

            if (str.Length > 0)
            {
                str = str.Substring(0, str.Length - 1);
                change.fomationMapStr = str;
            }

            if(oldStr.Length > 0)
            {
                oldStr = oldStr.Substring(0, oldStr.Length - 1);
            }

            Debug.Log("[DEBUG new str]: " + change.fomationMapStr);
            Debug.Log("[DEBUG old str]: " + oldStr);

            NetAPI.SendHttp(OpDefine.CSFormationChange, change, (data, ok) =>
            {
                if(ok)
                {
                    var newformation = (SCFormationChange)data.kBody;
                    ResetModelFixedPosition();

                    StaticData.playerData.InstPlayerData.UpdateBattleFormation(newformation.formationList);

                    SwitchTwoModel(index0,index1);
                    
                    ResetModelSize();
                    ResetModelNames();

                    CSRefreshSideHp sideHp = new CSRefreshSideHp();
                    sideHp.newFormation = change.fomationMapStr;
                    sideHp.oldFormation = oldStr;
                    NetAPI.SendSocket(OpDefine.CSRefreshSideHp, sideHp);
                }
            });
        }

        void ResetModelFixedPosition()
        {
            for (int i = 0; i < 4; i++)
            {
                modelTransform[i].position = fixedTransform[i].position;
            }
        }

        void SwitchTwoModel(int index0,int index1)
        {

            var temp0 = modelTransform[index0].GetComponent<UIFormationModel>().model;
            var temp1 = modelTransform[index1].GetComponent<UIFormationModel>().model;

            var heroId0 = modelTransform[index0].GetComponent<UIFormationModel>().heroId;
            var heroId1 = modelTransform[index1].GetComponent<UIFormationModel>().heroId;

            temp0.transform.SetParent(modelTransform[index1]);
            temp0.transform.localPosition = Vector3.zero;
            temp0.transform.localScale = Vector3.one;
            modelTransform[index1].GetComponent<UIFormationModel>().model = temp0;
            modelTransform[index1].GetComponent<UIFormationModel>().heroId = heroId0;

            temp1.transform.SetParent(modelTransform[index0]);
            temp1.transform.localPosition = Vector3.zero;
            temp1.transform.localScale = Vector3.one;
            modelTransform[index0].GetComponent<UIFormationModel>().model = temp1;
            modelTransform[index0].GetComponent<UIFormationModel>().heroId = heroId1;

            var shadow0 = modelTransform[index0].GetComponent<UIFormationModel>().shadow;
            var shadow1 = modelTransform[index1].GetComponent<UIFormationModel>().shadow;

            

            modelTransform[index1].GetComponent<UIFormationModel>().shadow.transform.SetParent(modelTransform[index0]);
            modelTransform[index0].GetComponent<UIFormationModel>().shadow.transform.SetParent(modelTransform[index1]);

            modelTransform[index1].GetComponent<UIFormationModel>().shadow.transform.localScale = new Vector3(2,1,0);
            modelTransform[index1].GetComponent<UIFormationModel>().shadow.transform.localPosition = Vector3.zero;
            //modelTransform[index1].GetComponent<UIFormationModel>().shadow.transform.localRotation = Quaternion.Euler(0, 0, 0);

            modelTransform[index0].GetComponent<UIFormationModel>().shadow.transform.localScale = new Vector3(2, 1, 0);
            modelTransform[index0].GetComponent<UIFormationModel>().shadow.transform.localPosition = Vector3.zero;
            //modelTransform[index0].GetComponent<UIFormationModel>().shadow.transform.localRotation = Quaternion.Euler(0, 0, 0);

            modelTransform[index0].GetComponent<UIFormationModel>().shadow = shadow1;
            modelTransform[index1].GetComponent<UIFormationModel>().shadow = shadow0;

            var tempScale = modelScales[index0];
            modelScales[index0] = modelScales[index1];
            modelScales[index1] = tempScale;
        }

        void ResetPosition(int index)
        {
            if( index<0 || index >3 ) return;

            var tran = fixedTransform[index];
            selection.transform.position = tran.position;
        }

        void ResetModelSize()
        {
            foreach(var tr in modelTransform)
            {
                tr.gameObject.SetActive(true);

                var model = tr.gameObject.GetComponent<UIFormationModel>().model;
                if(model.activeSelf)
                {
                    var ani = model.GetComponent<LegacyAnimation>();
                    ani.Play(@"standfight", WrapMode.Loop);
                }

                tr.gameObject.layer = LayerMask.NameToLayer("SceneActor");
            }

            var modelScale = 330f;
            modelTransform[0].transform.localScale = Vector3.one*1.0f* modelScale * modelScales[0];
            modelTransform[1].transform.localScale = Vector3.one*0.9f* modelScale * modelScales[1];
            modelTransform[2].transform.localScale = Vector3.one*0.9f* modelScale * modelScales[2];
            modelTransform[3].transform.localScale = Vector3.one*0.8f* modelScale * modelScales[3];
        }

        void ResetModelNames()
        {
            foreach(var obj in heroNamebk)
            {
                obj.SetActive(false);
            }

            int i = 0;
            foreach(var model in modelTransform)
            {
                i++;
                var kit = model.gameObject.GetComponent<UIFormationModel>();
                if (kit != null && kit.heroId!="")
                {
                    //var obj = kit.model;
                    if (model.gameObject.activeSelf)
                    {
                        string heroName = CommonMethod.GetHeroName(kit.heroId);//TableTextBlo.GetText(kit.heroName);
                        ShowHeroName(i - 1, heroName);
                    }
                }
            }
            
        }
    }
}